﻿Imports System.Reflection

MustInherit Class BaseClass
    ''' <summary>
    ''' method for safely disposing an object to prevent an exception being thrown
    ''' </summary>
    ''' <param name="objectToDispose">object</param>
    Protected Overridable Sub SafeDispose(ByRef objectToDispose As IDisposable)
        Try
            If objectToDispose IsNot Nothing Then
                objectToDispose.Dispose()
                objectToDispose = Nothing
            End If
        Catch oExp As Exception
            'Only log the exception
            LogException(oExp)
        End Try
    End Sub

    ''' <summary>
    ''' This method is used to log exceptions to the event viewer from static classes or methods
    ''' This method works with any type of exception.
    ''' </summary>
    ''' <param name="exceptionToLog">The error that needs to be logged</param>
    Public Shared Shadows Sub LogException(ByVal exceptionToLog As Exception)
        Dim szApp As String
        Try
            'get the calling applications name
            szApp = Assembly.GetCallingAssembly().GetName().Name
        Catch
            szApp = Constants.APP_NAME
        End Try

        LogExceptionI(exceptionToLog, 0, 0, szApp)
    End Sub

    ' <summary>
    ' This method is used to log exceptions to the event viewer from static classes or methods
    ' This method works with any type of exception.
    ' </summary>
    ' <param name="exceptionToLog">The error that needs to be logged</param>
    ' <param name="eventID">The event id number</param>
    ' <param name="category">The category for the event</param>
    ' <param name="appName">The name of the calling assembly</param>
    Friend Shared Sub LogExceptionI(ByVal exceptionToLog As Exception, ByVal eventID As Integer, ByVal category As Short, ByVal appName As String)
        Try
            Dim szUser As String = ""
            Try
                szUser = "(" + Thread.CurrentPrincipal.Identity.Name + ")"
            Catch
            End Try

            WriteEventLogEntry(appName, szUser + exceptionToLog.ToString(), EventLogEntryType.Error, eventID, category)
            'don't do anything - at least for now
        Catch
        End Try
    End Sub

    ''' <summary>
    ''' This method is used to log exceptions to the event viewer from static classes or methods
    ''' This method works with any type of exception.
    ''' </summary>
    ''' <param name="exceptionToLog">The error that needs to be logged</param>
    ''' <param name="eventID">The event id number</param>
    ''' <param name="category">The category for the event</param>
    Public Shared Shadows Sub LogException(ByVal exceptionToLog As Exception, ByVal eventID As Integer, ByVal category As Short)
        'have to code this here and not in a reusable method(even an internal method will mess this up) because
        'if it is in any other method than the one directly called by the code
        'that had the error, it takes that methods calling assembly name
        'rather than the one that had the error
        Dim szApp As String
        Try
            'get the calling applications name
            szApp = Assembly.GetCallingAssembly().GetName().Name
        Catch
            szApp = Constants.APP_NAME
        End Try

        LogExceptionI(exceptionToLog, eventID, category, szApp)
    End Sub

    ''' <summary>
    ''' Logs the event.
    ''' </summary>
    ''' <param name="messageToLog">message</param>
    Public Shared Shadows Sub LogEvent(ByVal messageToLog As String)
        'have to code this here and not in a reusable method(even an internal method will mess this up) because
        'if it is in any other method than the one directly called by the code
        'that had the error, it takes that methods calling assembly name
        'rather than the one that had the error
        Dim szApp As String
        Try
            szApp = Assembly.GetCallingAssembly().GetName().Name
        Catch
            szApp = Constants.APP_NAME
        End Try
        LogEvent(szApp, messageToLog)
    End Sub

    ''' <summary>
    ''' Logs the event.
    ''' </summary>
    ''' <param name="appName">app</param>
    ''' <param name="messageToLog">message</param>
    Friend Shared Shadows Sub LogEvent(ByVal appName As String, ByVal messageToLog As String)
        LogEvent(appName, messageToLog, False)
    End Sub

    ''' <summary>
    ''' Logs the event.
    ''' </summary>
    ''' <param name="appName">app</param>
    ''' <param name="messageToLog">message</param>
    ''' <param name="warningFlag">if set to <c>true</c> [warning].</param>
    Friend Shared Shadows Sub LogEvent(ByVal appName As String, ByVal messageToLog As String, ByVal warningFlag As Boolean)
        Dim eEventLogEntryType As EventLogEntryType = (If(warningFlag, EventLogEntryType.Warning, EventLogEntryType.Information))
        WriteEventLogEntry(appName, messageToLog, eEventLogEntryType, 0, 0)
    End Sub

    Private Shared Sub WriteEventLogEntry(szApp As String, szMessage As String, eEventLogEntryType As EventLogEntryType, iEventID As Integer, sCategory As Short)
        Try
            ValidateAndFixMessage(szMessage)
            EventLog.WriteEntry(szApp, szMessage, eEventLogEntryType, iEventID, sCategory)
            ' can't do anything
        Catch
        End Try
    End Sub

    Private Shared Sub ValidateAndFixMessage(ByRef messageToLog As String)
        'only log the first 10000 chars to avoid filling the eventlog. EventLog also errors if the
        'description is longer than 32766 characters.
        Const LOG_LENGTH As Integer = 1000
        If messageToLog.Length > LOG_LENGTH Then
            messageToLog = messageToLog.Substring(0, LOG_LENGTH) & Environment.NewLine & Environment.NewLine & " ... some data truncated due to the length of the event description"
        End If
    End Sub
End Class
